#pragma once 
#include <bits/stdc++.h>

/*****************************************************************************
 *! @brief 观察者模式
 * 
 * 
 * 
 * 
 * 
 *  
 ****************************************************************************/


template<typename Func>
class Events {
public:
    Events()  = default;
    ~Events() = default;
    Events(const Events& other)            = delete;
    Events& operator=(const Events& other) = delete;

    //注册观察者，支持右值引用
    int connect(Func&& f) {
        return assgin(f);
    }
   
    //注册观察者
    int connect(const Func& f) {
        return assgin(f);
    }
	
    //移除观察者
    void disconnect(int key) {
        _connections.erase(key);
    }

    void disconnectAll() {
        _connections.clear();
    }

	//通知所有的观察者
    template<typename... Args>
    void notify(Args&&... args) {
        for (auto& it: _connections) {
            it.second(std::forward<Args>(args)...);
        }
    }

private:
	//保存观察者并分配观察者的编号
    template<typename F>
    int assgin(F&& f) {
        int k = _observerId++;
        _connections.emplace(k, std::forward<F>(f));
        return k;
    }

    int                 _observerId=0;     //观察者对应的编号
    std::map<int, Func> _connections;      //观察者列表
};

int observer();